﻿//此程序作用：查看windows任务计划程序 中的自启动项
//你的电脑上可能查询结果为空，最好手动新建几个

#define _WIN32_DCOM

#include <windows.h>


#include <comdef.h>
#include <vector>
//  Include the task header file.
#include <taskschd.h>
#pragma comment(lib, "taskschd.lib")
#pragma comment(lib, "comsupp.lib")


class scheduledTaskInfo
{
public:
	wchar_t name[256] = { 0 };
	wchar_t description[256] = { 0 };
	wchar_t author[256] = { 0 };
	TASK_STATE status;
};

int main()
{
	//  ------------------------------------------------------
	//  Initialize COM.
	HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
	if (FAILED(hr))
	{
		printf("\nCoInitializeEx failed: %x", hr);
		return 1;
	}

	//  Set general COM security levels.
	hr = CoInitializeSecurity(
		NULL,
		-1,
		NULL,
		NULL,
		RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
		RPC_C_IMP_LEVEL_IMPERSONATE,
		NULL,
		0,
		NULL);

	if (FAILED(hr))
	{
		printf("\nCoInitializeSecurity failed: %x", hr);
		CoUninitialize();
		return 1;
	}

	//  ------------------------------------------------------
	//  Create an instance of the Task Service. 
	ITaskService *pService = NULL;
	hr = CoCreateInstance(CLSID_TaskScheduler,
		NULL,
		CLSCTX_INPROC_SERVER,
		IID_ITaskService,
		(void**)&pService);
	if (FAILED(hr))
	{
		printf("Failed to CoCreate an instance of the TaskService class: %x", hr);
		CoUninitialize();
		return 1;
	}

	//  Connect to the task service.
	hr = pService->Connect(_variant_t(), _variant_t(),
		_variant_t(), _variant_t());
	if (FAILED(hr))
	{
		printf("ITaskService::Connect failed: %x", hr);
		pService->Release();
		CoUninitialize();
		return 1;
	}

	//  ------------------------------------------------------
	//  Get the pointer to the root task folder.
	ITaskFolder *pRootFolder = NULL;
	hr = pService->GetFolder(_bstr_t(L"\\"), &pRootFolder);
	pService->Release();

	if (FAILED(hr))
	{
		printf("Cannot get Root Folder pointer: %x", hr);
		CoUninitialize();
		return 1;
	}

	//  -------------------------------------------------------
	//  Get the registered tasks in the folder.
	IRegisteredTaskCollection* pTaskCollection = NULL;
	hr = pRootFolder->GetTasks(NULL, &pTaskCollection);
	pRootFolder->Release();

	if (FAILED(hr))
	{
		printf("Cannot get the registered tasks.: %x", hr);
		CoUninitialize();
		return 1;
	}

	LONG numTasks = 0;
	hr = pTaskCollection->get_Count(&numTasks);

	if (numTasks == 0)
	{
		printf("\nNo Tasks are currently running");
		pTaskCollection->Release();
		CoUninitialize();
		return 1;
	}

	printf("\nNumber of Tasks : %d\n", numTasks);

	std::vector<scheduledTaskInfo> result;

	for (LONG i = 0; i < numTasks; i++)
	{
		IRegisteredTask* pRegisteredTask = NULL;
		pTaskCollection->get_Item(_variant_t(i + 1), &pRegisteredTask);

		BSTR taskName = NULL;
		pRegisteredTask->get_Name(&taskName);

		TASK_STATE taskState;
		pRegisteredTask->get_State(&taskState);

		ITaskDefinition *itaskdef = NULL;
		pRegisteredTask->get_Definition(&itaskdef);

		IRegistrationInfo *regInfo = NULL;
		itaskdef->get_RegistrationInfo(&regInfo);

		BSTR taskInfo = NULL, author = NULL;
		regInfo->get_Description(&taskInfo);
		regInfo->get_Author(&author);
		scheduledTaskInfo schdTaskInfo;
		


		if (taskName) {
			wcscpy_s(schdTaskInfo.name, taskName);
		}
		if (taskInfo) {
			wcscpy_s(schdTaskInfo.description, taskInfo);
		}

		if (author) {
			wcscpy_s(schdTaskInfo.author, author);
		}
		schdTaskInfo.status = taskState;
		
		itaskdef->Release();
		regInfo->Release();
		pRegisteredTask->Release();

		SysFreeString(taskName);
		SysFreeString(taskInfo);
		SysFreeString(author);
		result.emplace_back(schdTaskInfo);
	}

	for (auto p : result) {
		printf("name: %ws, author: %ws,description: %ws, state: %d\n", p.name, p.author,p.description,p.status);
	}

	pTaskCollection->Release();
	CoUninitialize();
	return 0;
}